package main

import (
	"fmt"
	"log"
	"strings"

	"github.com/valyala/fasthttp"
)

type Server struct {
	logicLayer Logic
}

func (srv *Server) Handle(ctx *fasthttp.RequestCtx) {
	ret := NewResult()
	// parse args
	args := parseArgs(ctx)
	// handle request
	if ctx.IsGet() && args.method == "getData" {
		if v, err := srv.get(args); err == nil {
			ret.WithValue(v).WithCode(0)
		} else {
			ret.WithError(err).WithCode(4002)
		}
	}

	// response
	if ret.code == 0 {
		msg := "[Info]: Response success to %s, "
		msg = msg + "TABLENAME = %s, query conditions = %s"
		log.Printf(msg, args.ip, args.table, args.query)
		ctx.Success("application/json", ret.Finish().bytes())
	} else {
		msg := "[Error]: Response error to %s, "
		msg = msg + "TABLENAME = %s, query conditions = %s, "
		msg = msg + "error reason: %v"
		log.Printf(msg, args.ip, args.table, args.query, ret.err)
		ctx.Error(ret.Finish().String(), ret.code)
	}
}

type Args struct {
	ip     string
	table  string
	method string
	path   string
	query  string
	conds  []Condition
}

func parseArgs(ctx *fasthttp.RequestCtx) (args Args) {
	args = Args{path: string(ctx.Path())}
	if ctx.IsGet() {
		args.ip = ctx.RemoteIP().String()
		args.table = string(ctx.QueryArgs().Peek("tablename"))
		args.method = string(ctx.QueryArgs().Peek("method"))
		args.query = string(ctx.QueryArgs().Peek("query"))
		if args.query != "" {
			conds := strings.Split(string(args.query), "|and|")
			args.conds = parseConds(conds)
		}
		msg := "[Info]: Receive GET request from %s. "
		msg = msg + "TABLENAME = %s, query conditions = %s"
		log.Printf(msg, args.ip, args.table, args.query)
	}
	return
}

func (srv *Server) get(args Args) ([]map[string]string, error) {
	if args.table == "" {
		log.Println("[Error]: Lack of parameter 'tablename'")
		return nil, ParseArgsErr
	} else {
		return srv.logicLayer.OpenNGet(args)
	}
}

var TableNotFound = fmt.Errorf("TableNotFound")
var KeyNotFound = fmt.Errorf("KeyNotFound")
var ParseArgsErr = fmt.Errorf("ParseArgsError")
var RequestArgsErr = fmt.Errorf("RequestArgsError")
